package com.kavin.collection.datastructure;

import org.junit.jupiter.api.Test;

import java.util.Objects;

/**
 * @ClassName DoubleLinkedList
 * @Description
 * @Author kavin
 * @Date 2022/8/15 11:05
 * @Version 1.0
 */
public class DoubleLinkedList {

    static class Node{
        public int value;
        public Node pre;
        public Node next;
        Node(){

        }
        Node(int value){
          this.value = value;
        }

        @Override
        public String toString() {
            return "Node." + "value=" + value ;
        }
    }


    private Node first;
    private Node last;
    private Integer size = 0;


    //头插法
    public void addFirst(Node node){
        if(Objects.isNull(first)){
            last = node;
        }else{
            node.next = first;
            first.pre = node;
        }
        first = node;
        size ++ ;
    }


    public  void addLast(Node node){

        if(Objects.isNull(first)){
            first = node;
        }else{
            last.next = node;
            node.pre = last;
        }
        last = node;
        size ++ ;
    }

    //value值相等的某个节点前加入
    public void addBeforeNode(int value,Node node){
        if(Objects.isNull(first)){
            return;
        }
        if(first.value == value){
            first = node;
            node.next = first;
            size ++ ;
            return;
        }
        Node temp = first;

        while (Objects.nonNull(temp)){
            if(temp.next.value == value){
                node.next = temp.next;
                node.pre = temp;
                temp.next.pre = node;
                temp.next = node;
                size ++ ;
                return;
            }
            temp = temp.next;
        }

        if(last.value == value){

            node.pre = last.pre;
            node.next = last;
            last.pre.next =node;
            last.pre = node;
            size ++ ;
        }

    }


    //value 值相等的某个节点后插入
    public void addAfterNode(int value,Node node) {
        if (Objects.isNull(first)) {
            return;
        }

        Node temp = first;
        while (Objects.nonNull(temp)) {

            if (temp.value == value) {
                node.pre = temp;
                node.next = temp.next;

                if(Objects.isNull(temp.next)){
                    temp.next = node;
                    last = node;
                    size ++ ;
                    return;
                }

                temp.next.pre = node;
                temp.next = node;
                size++;
                return;
            }
            temp = temp.next;
        }
    }
    //头部删除
    public void deleteFirst(){
        if(size == 1 ){
            first = null;
            last = null;
            size --;
            return;
        }

        first  = first.next;
        first.pre = null;
        size --;
    }



    //尾部删除
    public void deleteLast(){
        if(Objects.isNull(first)){
            return;
        }
        if(size == 1){
            first = null;
            size --;
            return;
        }
        last = last.pre;
        last.next = null;
        size--;
    }
    //按照值删除
    public void deleteByValue(int value){
        if(size == 0){
            return;
        }
        Node temp = first;
        while (Objects.nonNull(temp)){
            if(temp.value == value){
                if(temp.pre == null){ //first
                    return;
                }
                temp.pre.next = temp.next;

                if(temp.next == null){ //last
                    last = temp.pre;
                    last.next = null;
                    size -- ;
                    return;
                }

                temp.next.pre = temp.pre;
                size --;
            }
            temp = temp.next;

        }

    }



    //打印链表
    public void printDoubleLinkedList(){
        Node tmp = first;
        while(tmp != null){
            System.out.println(tmp);
            tmp = tmp.next;
        }
    }

    @Test
    public void test(){

        /*for( int i = 1 ; i < 10 ; i ++){
            Node node = new Node(i);
            addFirst(node);
        }

        addAfterNode(6,new Node(100));
        deleteByValue(6);
        deleteFirst();
        deleteLast();
        printDoubleLinkedList();*/

        addFirst(new Node(5));
        addAfterNode(5,new Node(6));

    }

}
